package dataImport.action.abstracts;

import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import dataImport.action.manager.EntityReaderManager;
import dataImport.exception.MissingReader;
import dataImport.exception.ReaderAlreadyFixedException;
import dataImport.model.abstracts.AbstractEntity;


public abstract class AbstractTempEntityReader extends AbstractEntityReader {

	private static final long serialVersionUID = -4975890369735211573L;

	private boolean fixed;

	protected final String fixText(final String text, final String entityName, final AbstractEntityReader abstractEntityReader) {

		final String PREFIX = "@" + entityName + ":";
		final String SUFFIX = "@";

		String newText = text;
		Pattern pattern = null;
		Matcher matcher = null;

		pattern = Pattern.compile(PREFIX + "\\w*" + SUFFIX);
		matcher = pattern.matcher(newText);

		while (matcher.find()) {
			final String id = matcher.group().replaceFirst(PREFIX, "").replaceFirst(SUFFIX, "");
			newText = this.replaceAll(newText, matcher.group(), abstractEntityReader.getEntityWithId(id));
		}

		return newText;
	}

	protected String replaceAll(final String text, final String regex, final AbstractEntity abstractEntity) {
		return text.replaceAll(regex, abstractEntity.toString());
	}

	protected abstract void checkRequiredReaders(final EntityReaderManager entityReaderManager) throws MissingReader;

	protected abstract void fixEntities(HashMap<String, AbstractEntity> newEntities, final EntityReaderManager entityReaderManager) throws MissingReader;

	public final void fixEntities(final EntityReaderManager entityReaderManager) throws MissingReader, ReaderAlreadyFixedException {

		if (this.isFixed()) {
			throw new ReaderAlreadyFixedException();
		}

		final HashMap<String, AbstractEntity> newEntities = new HashMap<String, AbstractEntity>();

		this.checkRequiredReaders(entityReaderManager);

		this.fixEntities(newEntities, entityReaderManager);

		this.fixed = true;

		this.abstractEntities = newEntities;
	}

	public boolean isFixed() {
		return this.fixed;
	}
}
